import os
import re
import time
import PyPDF2
import datetime
import requests
import pandas as pd
from requests import exceptions as request_exceptions


class SHICEconomy(object):
    def __init__(self):
        self.headers = {
            'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) '
                          'Chrome/95.0.4638.69 Safari/537.36'
        }
        self.start_string = '2019-01-01'
        self.resource_path = 'resource'
        self.result_file_path = 'result.csv'

    def create_date_list(self):
        start_date = datetime.datetime.strptime(self.start_string, "%Y-%m-%d")  # 将指定的字符串转为时间格式
        now_date = (datetime.datetime.now()).strftime("%Y-%m-%d")  # 获取当前的时间
        date_string_list = list()
        i = 0
        while True:
            date_i = (start_date + datetime.timedelta(days=i)).strftime('%Y-%m-%d')
            date_string = str(date_i).replace('-', '/')
            print("创建时间字符串 - 存储成功：", date_string)
            date_string_list.append(date_string)
            if date_i < now_date:
                i += 1
            else:
                break
        return date_string_list

    def request_server(self, url):
        request_count = 0
        request_total = 3
        result = {'status': False}
        while request_count < request_total:
            try:
                response = requests.get(url=url, headers=self.headers, timeout=5)
                result = {'status': True, 'response': response}
                break
            except request_exceptions.ConnectTimeout:
                print(f'{url} - 请求失败 ConnectTimeout!\n', end='')
            except request_exceptions.RequestException:
                print(f'{url} - 请求失败 RequestException!\n', end='')
            request_count += 1
            time.sleep(1)
        return result

    def pdf_download(self, file_path, pdf_url):
        """ pdf下载 """
        download_result = {'status': False}
        request_result = self.request_server(url=pdf_url)
        if request_result['status'] is False:
            return download_result
        response = request_result['response']
        with open(file_path, 'wb') as fis:
            for chunk in response.iter_content(chunk_size=1000):
                fis.write(chunk)
                fis.flush()
            print(f'下载完成：{file_path}')
        download_result = {'status': True}
        return download_result

    def read_finished_download_path(self):
        finished_download_pdf_list = list()
        for path in os.listdir(self.resource_path):
            file_path = f'{self.resource_path}/{path}'
            finished_download_pdf_list.append(file_path)
        return finished_download_pdf_list

    def pdf_download_controller(self, date_string_list=[]):
        """ pdf下载控制 """
        finished_download_pdf_list = self.read_finished_download_path()  # 获取已经下载的pdf地址
        for date_string in date_string_list:
            file_path = f"{self.resource_path}/{date_string.replace('/', '-')}.pdf"  # 拼接下载文件路径
            if file_path in finished_download_pdf_list:
                print(f"已下载：{file_path}")
                continue
            url = f'https://www.cfets-nex.com.cn/Market/marketOverview/dailyReview?Date={date_string}'
            request_result = self.request_server(url=url)
            if request_result['status'] is False:  # pdf请求状态
                print(f"请求失败：{url}")
                continue
            html_text = request_result['response'].text
            pdf_re = re.search(pattern="银行间货币市场.*?href='(.*?)'", string=html_text, flags=re.S)  # 匹配pdf下载地址
            pdf_prefix = 'https://www.cfets-nex.com.cn'
            if pdf_re is None:
                print(f"当天无数据（或还未发布数据）：{url}")
                continue
            else:
                pdf_suffix = pdf_re.group(1)
            pdf_url = pdf_prefix + pdf_suffix
            download_result = self.pdf_download(file_path, pdf_url)  # 下载pdf
            if download_result['status'] is False:  # pdf下载状态
                print(f"下载失败：{url}")
                continue
            finished_download_pdf_list.append(file_path)  # 存储下载成功之后的文件地址
        return finished_download_pdf_list

    def pdf_parse(self, pdf_path_list):
        for file_path in pdf_path_list:
            column1_content = file_path.split('/')[-1].split('.pdf')[0]
            try:
                pdffile = open(file=file_path, mode='rb')  # 读取pdf文件
                pdfreader = PyPDF2.PdfFileReader(pdffile)
            except Exception:
                content = f"{column1_content},None,None\n"
                self.csv_save(content)
                print(f"{file_path} - PDF读取异常")
                continue
            pdf_content = ''
            for i in range(pdfreader.numPages):  # 获取pdf的总页数
                page_content = pdfreader.getPage(i)  # 获取第i页的对象
                pdf_content += page_content.extractText()  # 提取第i页的对象内容
            column2_1_re = re.search(pattern='今.{0,1}资金面(.*?)。', string=pdf_content, flags=re.S)
            column2_2_re = re.search(pattern='早盘资金面(.*?)。', string=pdf_content, flags=re.S)
            if column2_1_re:
                column2_content = f'{column2_1_re.group()}'.replace('\n', '').replace(',', '，')
            elif column2_2_re:
                column2_content = f'{column2_2_re.group()}'.replace('\n', '').replace(',', '，')
            else:
                column2_content = 'None'
            column3_1_re = re.search(pattern='资金面情绪指数(.*?)\n', string=pdf_content, flags=re.S)
            column3_2_re = re.search(pattern='今日全天的资金面指数(.*?)\n', string=pdf_content, flags=re.S)
            column3_3_re = re.search(pattern='今日资金.{0,1}情绪指数(.*?)\n', string=pdf_content, flags=re.S)
            column3_4_re = re.search(pattern='情绪指数(.*?)\n', string=pdf_content, flags=re.S)
            if column3_1_re:
                column3_content = f'资金面情绪指数{column3_1_re.group(1)}'.replace('\n', '').replace(',', '，')
            elif column3_2_re:
                column3_content = f'今日全天的资金面指数{column3_2_re.group(1)}。'.replace('\n', '').replace(',', '，')
            elif column3_3_re:
                column3_content = f'{column3_3_re.group()}'.replace('\n', '').replace(',', '，')
            elif column3_4_re:
                column3_content = f'{column3_4_re.group()}'.replace('\n', '').replace(',', '，')
            else:
                column3_content = 'None'
            content = f"{column1_content},{column2_content},{column3_content}\n"
            self.csv_save(content)
            print("写入成功：", column1_content, column2_content, column3_content)
        return True

    def create_file(self):
        if os.path.exists(self.resource_path) is False:
            os.mkdir(self.resource_path)
        with open(file=self.result_file_path, mode='w', encoding='utf-8') as fis:
            fis.write('日期,今日资金面,资金面情绪指数\n')

    def csv_save(self, content):
        with open(file=self.result_file_path, mode='a+', encoding='utf-8') as fis:
            fis.write(content)

    def csv_save_as_xlsx(self):
        """ 读取csv文件将结果写入xlsx """
        filename_prefix = os.path.splitext(self.result_file_path)[0]  # 切割文件路径以及后缀
        df = pd.read_csv(self.result_file_path, encoding='utf-8', dtype='object')
        df.to_excel(f"{filename_prefix}.xlsx", index=False)
        print("csv 转 xlsx 成功!")

    def runs(self):
        self.create_file()
        date_string_list = self.create_date_list()
        pdf_path_list = self.pdf_download_controller(date_string_list)
        self.pdf_parse(pdf_path_list)
        self.csv_save_as_xlsx()


if __name__ == '__main__':
    SHICEconomy().runs()
